/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package assignment2;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableModel;

/**
 * InventoryViewer Class:
 * This class is used to display all current inventory items, and their respective statistics (such as stock, quality etc.)
 * @author Vale
 *
 */
public class InventoryViewer extends InventoryList implements ActionListener, WindowListener {

    private JFrame viewInvFrame;
    private JScrollPane table;
    private JPanel headingPanel;
    private JPanel buttonPanel;
    private InventoryList inventory;
    private InventoryList inventoryRestore;
    private JButton backButton;
    private JButton invOrderButton;
    private JButton addInvButton;
    private JButton remInvButton;
    private JButton editInvButton;
    private JTable invTable;
    private ProductList products;
    private DefaultTableModel invTableModel = new DefaultTableModel();
    private static final String HEADING_FONT = "Heading";
    private static final int HEADING_FONT_SIZE = 20;
    private static final String FRAME_HEADING = "Inventory Stats";
    private static final String GUI_TITLE = "Inventory Information";
    private static final String EDIT_BUTTON = "Edit Inventory Item";
    private static final String ADD_BUTTON = "Add New Inventory Item";
    private static final String REM_BUTTON = "Remove Inventory Item";
    private static final String BACK_BUTTON = "Back";
    private static final String INVORD_BUTTON = "Order Inventory";
    private static final int FRAME_WIDTH = 400;
    private static final int FRAME_HEIGHT = 500;
    private static final int BPANEL_ROWS = 3;
    private static final int BPANEL_COLS = 2;
    private static final int BUTTON_SPACING = 5;
    private static final int TABLE_COLS = 6;
    private static final String TABLE_HEAD_COL1 = "Inventory Item";
    private static final String TABLE_HEAD_COL2 = "Current Stock";
    private static final String TABLE_HEAD_COL3 = "Units";
    private static final String TABLE_HEAD_COL4 = "Cost/Unit";
    private static final String TABLE_HEAD_COL5 = "Quality";
    private static final String TABLE_HEAD_COL6 = "Required";
    private static final int ZERO = 0;

    public InventoryViewer(InventoryList invList, ProductList prodList) {
        //Create new Objects
        inventory = invList;
        products = prodList;
        inventoryRestore = invList;
        viewInvFrame = new JFrame(FRAME_HEADING);
        headingPanel = new JPanel();
        buttonPanel = new JPanel();
        invOrderButton = new JButton(INVORD_BUTTON);
        backButton = new JButton(BACK_BUTTON);
        addInvButton = new JButton(ADD_BUTTON);
        remInvButton = new JButton(REM_BUTTON);
        editInvButton = new JButton(EDIT_BUTTON);

        //Edit Frames properties
        viewInvFrame.addWindowListener(this);
        viewInvFrame.setResizable(false);
        viewInvFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        viewInvFrame.setLayout(new BorderLayout());

        //Format Heading
        JTextArea heading = new JTextArea(GUI_TITLE);
        Color bgColour = viewInvFrame.getBackground();
        heading.setBackground(bgColour);
        Font headerFont = new Font(HEADING_FONT, Font.BOLD, HEADING_FONT_SIZE);
        heading.setFont(headerFont);
        headingPanel.add(heading);

        //Add Buttons
        buttonPanel.setLayout(new GridLayout(BPANEL_ROWS, BPANEL_COLS, BUTTON_SPACING, BUTTON_SPACING));
        buttonPanel.add(addInvButton);
        addInvButton.addActionListener(new AddInventory());
        buttonPanel.add(remInvButton);
        remInvButton.addActionListener(new RemoveInventory());
        buttonPanel.add(editInvButton);
        editInvButton.addActionListener(new EditInventory());
        buttonPanel.add(invOrderButton);
        invOrderButton.addActionListener(new OrderInventory());
        buttonPanel.add(backButton);
        backButton.addActionListener(this);

        //Print main Product table
        printInvTable();

        //Add content to frame
        viewInvFrame.getContentPane().add(headingPanel, BorderLayout.NORTH);
        viewInvFrame.getContentPane().add(table, BorderLayout.CENTER);
        viewInvFrame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
        viewInvFrame.setVisible(true);
        viewInvFrame.pack();
    }

    /**
     * void actionPerformed(ActionEvent e) Method:
     * This is called when the "Back" button is pressed. It calls dispose(), which frees up all currently used resources by the current frame (viewProdFrame)
     * and consequently closes it.
     *
     */
    public void actionPerformed(ActionEvent e) {
        viewInvFrame.dispose();
    }

    /**
     * void windowOpened(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowOpened(WindowEvent e) {
    }

    /**
     * void windowClosing(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has been implemented such that if the frame is closed without using the specified "Back"
     * button, the resources used by the frame are released.
     *
     */
    public void windowClosing(WindowEvent e) {
        viewInvFrame.dispose();
    }

    /**
     * void windowClosed(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented, as its purpose has been covered by the 'windowClosing' event.
     *
     */
    public void windowClosed(WindowEvent e) {
    }

    /**
     * void windowIconified(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowIconified(WindowEvent e) {
    }

    /**
     * void windowDeiconified(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowDeiconified(WindowEvent e) {
    }

    /**
     * void windowActivated(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowActivated(WindowEvent e) {
    }

    /**
     * void windowDeactivated(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowDeactivated(WindowEvent e) {
    }

    /**
     * AddInventory Inner Class:
     * This inner class is used as a listener to the "Add Inventory Item" button. It creates a new instance of the class InventoryAdder, which is used to add inventory items to the list.
     *
     */
    public class AddInventory implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            new InventoryAdder(inventory, products, viewInvFrame);
        }
    }

    /**
     * RemoveInventory Inner Class:
     * This inner class is used as a listener to the "Remove Inventory Item" button. It is used to remove the selected inventory items from the list on the viewing interface.
     *
     */
    public class RemoveInventory implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            int[] rowIndices = invTable.getSelectedRows();
            for (int i = ZERO; i < rowIndices.length; i++) {
                inventory.remove(rowIndices[i]);
                invTableModel.removeRow(rowIndices[i]);
            }
//            invTableModel.fireTableDataChanged();
        }
    }

    /**
     * EditInventory Inner Class:
     * This inner class is used as a listener to the "Edit Inventory Item" button. It creates a new instance of the InventoryEditor class, which is used to edit the currently
     * selected inventory item in the inventory list.
     *
     */
    public class EditInventory implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            new InventoryEditor(inventory.get(invTable.getSelectedRow()), inventory, products, viewInvFrame);
        }
    }

    /**
     * OrderInventory Inner Class:
     * This inner class is used as a listener to the "Order Inventory" button. It creates a new instance of the InventoryOrderer class, which is used to display the required stock
     * to be ordered, such that all products can be manufactured
     *
     */
    public class OrderInventory implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            new InventoryOrderer(inventory, products);
        }
    }

    /**
     * InventoryViewer Constructor:
     * This is the constructor for the InventoryViewer class. It takes the current inventory list as a parameter, and then displays the interface containg all of the relevant data
     * pertaining to the inventory list.
     *
     */
    

    /**
     * void printInvTable() Method:
     * This method is used to print the table of inventory items that currently exist in the list, along with the specific information for each item. It also disables direct
     * editing of the table itself.
     *
     */
    private void printInvTable() {
        int tableSize = inventory.getInvList().size();
        Object[][] rowData = new Object[tableSize][TABLE_COLS];
        Object[] columnNames = {TABLE_HEAD_COL1, TABLE_HEAD_COL2, TABLE_HEAD_COL3, TABLE_HEAD_COL4, TABLE_HEAD_COL5, TABLE_HEAD_COL6};
        for (int i = ZERO; i < tableSize; i++) {
            Object[] rowNum = {inventory.getInvList().get(i).getInvName(), inventory.getInvList().get(i).getInvStock(), inventory.getInvList().get(i).getInvUnits(), inventory.getInvList().get(i).getInvCost(), inventory.getInvList().get(i).getInvQualityText(), getRequiredInventory(i)};
            rowData[i] = rowNum;
        }
        invTable = new JTable(invTableModel) {

            public boolean isCellEditable(int rowIndex, int colIndex) {
                return false;
            }
        };
        invTableModel.setDataVector(rowData, columnNames);
        invTable.setRowSelectionAllowed(true);

        table = new JScrollPane(invTable);

    }

    /**
     * int getRequiredInventory(int invListIndex) Method:
     * This method is used to get the required inventory for each different inventory item. It does this by searching each product in the product list to determine
     * if the product requires the inventory item, and if so, increments the inventory required.
     * @param The index of the inventory item in the inventory list array
     * @return returns the number of inventory items required to produce the scheduled products
     *
     */
    public int getRequiredInventory(int invListIndex) {
        Inventory invItem = inventory.get(invListIndex);
        InventoryList prodInvList;
        invItem.setInvReqd(ZERO);
//            for (int j = 0; j < inventory.size(); j++) {
//                inventory.get(j).setInvReqd(ZERO);
//            }
        for (int i = ZERO; i < products.size(); i++) {
            prodInvList = products.get(i).getInventList();
            try {
            for (int k = 0; k < prodInvList.size(); k++) {
                if (prodInvList.get(k).getInvName().equals(invItem.getInvName())) {
                    invItem.setInvReqd(invItem.getInvReqd() + products.get(i).getProdSched());
                } else {
                    continue;
                }
            }
        } catch (Exception x) {
            continue;
        }
        }
        return inventory.get(invListIndex).getInvReqd();
    }
}
